home *** CD-ROM | disk | FTP | other *** search
- /*
- ARTemis (Graphic Editor for FM-TOWNS)
- (c) MATSUUCHI Ryosuke 1992,1993
-
- subgrp.c
-
- 補助グラフィック関数群
-
-
- ★描画
- * void mist(int x,int y,int xlen,int ylen,int col)
- void aapset(int x, int y, int col, int gray) //(x,y):16bit fixed-point
- * void aaline(int x1,int y1,int x2,int y2,int col,pen_t *pen,int gray)
- * void do_paint(int x,int y)
- * void psetWithPen(int x,int y,int col,pen_t *pen,bool conc_sw)
- * void lineWithPen(int x1,int y1,int x2,int y2,int col,pen_t *pen,
- bool first)
- * void inverse(int x,int y,int xlen,int ylen)
-
- ★特殊描画
- void plot_mat3(int x, int y, int mat[3][3])
- void plot_diffuse(int x, int y)
- void plot_sharp(int x,int y)
- void plot_sand(int x,int y)
- void plot_airbrush_start(void)
- void plot_airbrush(int x,int y)
- * void plot_pen_func(int x,int y,pen_t *pen, void (*func)(int x,int y))
- * void plot_pen_diffuse(int x, int y, pen_t *pen)
- * void plot_pen_sand(int x,int y, pen_t *pen)
- * void blot_plot(int x, int y, int color, int branch, int depth)
- * void blot2_plot(int x0, int y0, int color, int branch, int depth)
-
- ★描画アルゴリズム
- * void do_line(int x1,int y1,int x2,int y2,void func(int x,int y)!)
- * void do_boxline(int x1,int y1,int x2,int y2,void func(int x,int y)!)
- * void do_boxfill(int x1,int y1,int x2,int y2,
- void func(int x1,int x2,int y)!)
- * void do_ellipse(int x,int y,int rx,int ry,void func(int x,int y)!)
- * void do_ellipsefill(int x,int y,int rx,int ry,
- void func(int x1,int x2,int y)!)
-
- ★各種コマンド
- void commandPFline_sub(int cmd)
- * void commandPFline()
- * void commandPFPset()
- * void commandBlot()
- * void commandDiffuse()
- * void commandSand()
- * void commandGoshi()
- * void commandPaint()
- * void commandFreeTest()
- void commandPolygon_sub(void func()!, bool eachbackup)
- // func : (x1,x2,y) の引数で呼び出される
- * void commandDiffuseArea()
- * void commandSharp()
- * void commandSandArea()
- * void cmd_polygon()
-
- ★文字描画
- void grp_putchar_sub(char *dest, char *src, bool kanji, int col)
- void grp_putchar(int x, int y, int c, int col, int style)
- * void ART_putstr_style(int x, int y, char *str, int col, int style)
- * void ART_putstr(int x, int y, char *str, int col)
- * void ARTputstr12(int x,int y, char *str, int forecol, int backcol)
-
- ★計算
- * int mixcol(int col1, int col2, int rate, bool rnd)
- * int my_rand()
-
- */
-
-
- // アンチエイリアス描画をするかしないか
- #define NO_AA
-
- #include <stdio.h>
- #include <egb.h>
- #include <stdlib.h>
- #include <msdos.cf>
- #include <fnt.h>
- #include <ctype.h>
- #include <memory.h>
- #include <limits.h>
-
- #include "ge.h"
- #include "plt16.h"
- #include "math2.h"
- #include "decimal.h"
- #include "imageman.h"
- #include "dispman.h"
-
- /*--------------------------------------------------------*/
- /* 網目模様の描画 */
- /*--------------------------------------------------------*/
-
-
- void mist(int x,int y,int xlen,int ylen,int col) // 網目模様の描画
- {
- int i;
- for (i=0; i<ylen-xlen; i+=2)
- gline(x,y+i,x+xlen-1,y+xlen-1+i,col,DrawNORMAL);
- for ( ; i<ylen; i+=2)
- gline(x,y+i,x+ylen-1-i,y+ylen-1,col,DrawNORMAL);
- for (i=2; i<xlen-ylen; i+=2)
- gline(x+i,y,x+ylen-1+i,y+ylen-1,col,DrawNORMAL);
- for ( ; i<xlen; i+=2)
- gline(x+i,y,x+xlen-1,y+xlen-1-i,col,DrawNORMAL);
- }
-
-
- void inverse(int x,int y,int xlen,int ylen) // 白黒反転
- {
- if(DMgetifonepage())
- {
- grboxfill(x,y,xlen,ylen,menu_plt(White),DrawXOR);
- }
- else
- {
- int white = menu_plt(White), black = menu_plt(Black);
- int i,j;
- for(i=0; i<ylen; i++)
- {
- for(j=0; j<xlen; j++)
- {
- int c = gpoint(x+j,y+i);
- if (c==white) gpset(x+j,y+i,black,DrawNORMAL);
- if (c==black) gpset(x+j,y+i,white,DrawNORMAL);
- }
- }
- }
- }
-
-
- /*--------------------------------------------------------*/
- /* アンチエイリアシング直線描画 */
- /*--------------------------------------------------------*/
-
-
- #ifndef NO_AA
-
- static void aapset(int x, int y, int col, int gray)
- // (x,y) : 16bit fixed-point 座標
- {
- x = (x+128)>>8; // 8bit fixed-point へ変換
- y = (y+128)>>8;
- int x1,x2,y1,y2,h1,h2,v1,v2,a11,a12,a21,a22;
- x1 = x & 0xffffff00;
- x2 = x1 + 0x100;
- y1 = y & 0xffffff00;
- y2 = y1 + 0x100;
- h1 = x2 - x;
- h2 = x - x1;
- v1 = y2 - y;
- v2 = y - y1;
- a11 = (h1*v1)>>8;
- a12 = (h1*v2)>>8;
- a21 = (h2*v1)>>8;
- a22 = (h2*v2)>>8;
- x1 >>= 8;
- y1 >>= 8;
- x2 >>= 8;
- y2 >>= 8;
- if (a11 > 0)
- {
- if (a11 >= 256)
- gpset(x1,y1,col,DrawNORMAL);
- else
- EIMgraypset(x1,y1,col,a11);
- }
- if (a21 > 0)
- {
- if (a21 >= 256)
- gpset(x2,y1,col,DrawNORMAL);
- else
- EIMgraypset(x2,y1,col,a21);
- }
- if (a12 > 0)
- {
- if (a12 >= 256)
- gpset(x1,y2,col,DrawNORMAL);
- else
- EIMgraypset(x1,y2,col,a12);
- }
- if (a22 > 0)
- {
- if (a22 >= 256)
- gpset(x2,y2,col,DrawNORMAL);
- else
- EIMgraypset(x2,y2,col,a22);
- }
- }
-
- #endif
-
-
- void aaline(int x1, int y1, int x2, int y2, int col, pen_t *pen, int gray)
- {
- #ifdef NO_AA
- lineWithPen(x1,y1,x2,y2,col,pen,YES);
- #else
- int dx,dy,r;
- dx = _abs(x2-x1);
- dy = _abs(y2-y1);
- if (dx==0 && dy==0)
- {
- gpset(x1,y1,col,DrawNORMAL);
- return;
- }
- if (dx < dy)
- {
- r = (dx << 16) / dy;
- if (y1 > y2)
- { swap(y1,y2); swap(x1,x2); }
- if (x1 > x2)
- r = -r;
- int iy,ix;
- ix = x1<<16;
- for (iy = y1; iy <= y2; iy++,ix+=r)
- aapset(ix,iy<<16,col,256);
- }
- else
- {
- r = (dy << 16) / dx;
- if (x1 > x2)
- { swap(y1,y2); swap(x1,x2); }
- if (y1 > y2)
- r = -r;
- int iy,ix;
- iy = y1<<16;
- for (ix = x1; ix <= x2; ix++,iy+=r)
- aapset(ix<<16,iy,col,256);
- }
- #endif
- }
-
-
- /*--------------------------------------------------------*/
- /* ペイントルーチン */
- /*--------------------------------------------------------*/
-
- typedef struct {
- short int x,y;
- short int px1,px2,py;
- bool mark;
- } STACK;
-
- static STACK *check(int px1,int px2,int py,int sx1,int sx2,int sy,int y,int border, STACK *stack, int stacksize, STACK *sp)
- // 新しい sp を返す
- {
- int x;
- bool in_border;
- if (y<0 || EIMgetysize()<=y)
- return sp;
- in_border = YES;
- for (x=sx1; x<=sx2; x++) {
- if (in_border) {
- if (EIMpoint(x,y)==border) {
- if (!(y==py&&px1<=x&&x<=px2) && sp+1 < stack+stacksize) {
- sp++;
- sp->x = x;
- sp->y = y;
- sp->px1 = sx1;
- sp->px2 = sx2;
- sp->py = sy;
- sp->mark = TRUE;
- }
- in_border = NO;
- }
- } else {
- if (EIMpoint(x,y) != border)
- in_border = YES;
- }
- }
- return sp;
- }
-
- static void delete(int sx1,int sx2,int sy,STACK *oldsp, STACK *stack, STACK *sp)
- {
- STACK *p,*q;
- for (p=stack; p<=oldsp; p++) {
- if (p->y == sy && sx1 <= p->x && p->x <= sx2) {
- p->mark = NO;
- for (q = oldsp+1; q<=sp; q++) {
- if (q->y == p->py && p->px1 <= q->x && q->x <= p->px2)
- q->mark = FALSE;
- }
- }
- }
- }
-
- static void _do_paint(int x,int y,int col)
- {
- #define STACKSIZE 600
- STACK stack[STACKSIZE];
- STACK *sp;
-
- STACK *oldsp;
- int sx,sx1,sx2,sy;
- int px1,px2,py;
- int border;
- int mix = getmixrate();
-
- border = EIMpoint(x,y);
- sp = stack;
- sp->x = x;
- sp->y = y;
- sp->px1 = 0;
- sp->px2 = 0;
- sp->py = 0;
- sp->mark = YES;
- while (sp >= stack) {
- if (sp->mark) {
- sx = sp->x;
- sy = sp->y;
- px1 = sp->px1;
- px2 = sp->px2;
- py = sp->py;
- short *ip;
- for (sx1=sx,ip=(short*)EIMadrs(sx1,sy);
- sx1 > 0 && *(ip-1) == border;
- sx1--,ip--)
- ;
- for (sx2=sx,ip=(short*)EIMadrs(sx2,sy);
- sx2 < EIMgetxsize()-1 && *(ip+1) == border;
- sx2++,ip++)
- ;
- EIMgrayhline(sx1,sx2,sy,col,mix,NO);
- oldsp = --sp;
- sp=check(px1,px2,py,sx1,sx2,sy,sy+1,border, stack, STACKSIZE, sp);
- sp=check(px1,px2,py,sx1,sx2,sy,sy-1,border, stack, STACKSIZE, sp);
- delete(sx1,sx2,sy,oldsp, stack,sp);
- } else
- sp--;
- }
- }
-
- void do_paint(int x,int y)
- {
- _do_paint(x,y,forecol);
- }
-
-
- /*--------------------------------------------------------*/
- /* 混色処理 */
- /*--------------------------------------------------------*/
-
-
- /* 新しいrand()が合わなくなったんで自家製に切り換え 1993 3/6 */
- int my_rand() // by 戸田 浩
- {
- static unsigned int next = 1 ;
- next = next * 1103515245 + 12345 ;
- return (unsigned int)( next / 65536 ) % 32768 ;
- }
-
-
- int mixcol(int col1, int col2, int rate, bool rnd)
- // rnd : 乱数によりディザリングするかどうかのスイッチ
- {
- short int r1,g1,b1, r2,g2,b2;
- if (rate == 0)
- return col1;
- if (rate == 256)
- return col2;
- r1 = (col1 >> 5) & 31;
- g1 = (col1 >> 10) & 31;
- b1 = col1 & 31;
- r2 = (col2 >> 5) & 31;
- g2 = (col2 >> 10) & 31;
- b2 = col2 & 31;
- if (!rnd)
- {
- short int nr = 256-rate;
- r1 = ((r1 * nr + r2 * (short int)rate + 128) >> 8);
- g1 = ((g1 * nr + g2 * (short int)rate + 128) >> 8);
- b1 = ((b1 * nr + b2 * (short int)rate + 128) >> 8);
- }
- else
- {
- #define R ((short int)my_rand() & 255)
- short int nr = 256-rate;
- r1 = ((r1 * nr + r2 * (short int)rate + R) >> 8);
- g1 = ((g1 * nr + g2 * (short int)rate + R) >> 8);
- b1 = ((b1 * nr + b2 * (short int)rate + R) >> 8);
- #undef R
- }
- return (g1 << 10) + (r1 << 5) + b1;
- }
-
-
- /*--------------------------------------------------------*/
- /* 濃淡付きPSET */
- /*--------------------------------------------------------*/
-
-
- void psetWithPen(int x,int y,int col,pen_t *pen,bool conc_sw)
- {
- if (mixrate == 256)
- conc_sw = NO;
- void hdraw(int x0,int y0,int dx,int xlen,int dy, short *graymap)
- {
- EIMgrayhline_map(x0+dx,x0+dx+xlen-1,y0+dy,col,graymap,conc_sw);
- }
- pen_fill(pen, hdraw, x,y,YES);
- }
-
-
- /*--------------------------------------------------------*/
- /* ぼかし処理 */
- /*--------------------------------------------------------*/
-
-
- static void plot_mat3(int x, int y, int mat[3][3])
- {
- if (mode != MODE32K)
- return;
- int max_x, max_y;
- max_x = EIMgetxsize() - 1;
- max_y = EIMgetysize() - 1;
- if (x < 0 || y < 0 || max_x < x || max_y < y)
- return;
- int total[3]; // GRB各要素の強さの合計
- int ix,iy; // x,y について -1,0,1 と変化する変位
- int ix1,ix2,iy1,iy2;
- total[0] = total[1] = total[2] = 0;
- ix1 = _max(x-1,0 ) - x;
- ix2 = _min(x+1,max_x) - x;
- iy1 = _max(y-1,0 ) - y;
- iy2 = _min(y+1,max_y) - y;
- char *ep0,*ep; int linsiz;
- ep0 = EIMadrs_back(x+ix1, y+iy1);
- linsiz = EIMgetxbytes();
- for (iy=iy1; iy<=iy2; iy++,ep0+=linsiz)
- {
- ep = ep0;
- for (ix=ix1; ix<=ix2; ix++,ep+=2)
- {
- int c = *(short*)ep;
- int p = mat[iy+1][ix+1];
- total[0] += getG(c) * p;
- total[1] += getR(c) * p;
- total[2] += getB(c) * p;
- }
- }
- #define COL_AVR(a) ((total[a] + 128) >> 8)
- int t1,t2,t3;
- t1 = _lim(COL_AVR(0),0,31);
- t2 = _lim(COL_AVR(1),0,31);
- t3 = _lim(COL_AVR(2),0,31);
- EIMpset(x, y, GRB(t1,t2,t3), DrawNORMAL);
- #undef COL_AVR
- }
-
-
- static void plot_diffuse(int x, int y)
- // 1ドットに対してボカシを実行する
- {
- static int mat[3][3] = {{23,23,23},{23,72,23},{23,23,23}};
- plot_mat3(x,y,mat);
- }
-
-
- static void plot_sharp(int x,int y)
- {
- static int mat[3][3] = {{-16,-16,-16},{-16,384,-16},{-16,-16,-16}};
- plot_mat3(x,y,mat);
- }
-
-
- /*--------------------------------------------------------*/
- /* 砂処理 */
- /*--------------------------------------------------------*/
-
-
- static void plot_sand(int x,int y)
- {
- int i,c,grb[3];
- c = EIMpoint_back(x,y);
- grb[0]=getG(c), grb[1]=getR(c), grb[2]=getB(c);
- int r;
- r = rand() % 3;
- for (i=0; i<3; i++)
- {
- switch(r)
- {
- case 0:
- if (grb[i] > 0)
- grb[i]--;
- break;
- case 1:
- if (grb[i] < 31)
- grb[i]++;
- break;
- }
- }
- c = GRB(grb[0],grb[1],grb[2]);
- EIMpset(x,y,c,DrawNORMAL);
- }
-
-
- /*--------------------------------------------------------*/
- /* ペン先について任意の処理を行う */
- /*--------------------------------------------------------*/
-
-
- static void plot_pen_func(int x, int y, pen_t *pen, void (*func)(int x,int y))
- {
- void hline(int x0,int y0,int dx,int xlen,int dy, short *graymap)
- {
- int i;
- for (i=0; i<xlen; i++)
- func(x0+dx+i, y0+dy);
- }
- pen_fill(pen, hline, x,y, YES);
- }
-
-
- void plot_pen_diffuse(int x, int y, pen_t *pen)
- // ペンの形状にあわせた「ボカシ」を実行する
- {
- plot_pen_func(x,y,pen,plot_diffuse);
- }
-
-
- void plot_pen_sand(int x,int y, pen_t *pen)
- // ペンの形状にあわせた「ザラザラ化」を実行する
- {
- plot_pen_func(x,y,pen,plot_sand);
- }
-
-
- void lineWithPen(int x1,int y1,int x2,int y2,int col,pen_t *pen,bool first)
- // first : 最初の点を描画するかどうか
- {
- int xr,yr,r,x,y;
- xr = _abs(x2-x1), yr = _abs(y2-y1);
- if (first)
- psetWithPen(x1,y1,col,pen,YES);
- if (xr==0 && yr==0)
- ;
- else if (xr > yr)
- {
- r = (yr<<16) / xr;
- if (y1 > y2)
- r = -r;
- if (x1 < x2)
- {
- for (x=x1+1,y=(y1<<16)+0x8000+r; x<=x2; x++,y+=r)
- psetWithPen(x,(y>>16),col,pen,YES);
- }
- else
- {
- for (x=x1-1,y=(y1<<16)+0x8000+r; x>=x2; x--,y+=r)
- psetWithPen(x,(y>>16),col,pen,YES);
- }
- }
- else
- {
- r = (xr << 16) / yr;
- if (x1 > x2)
- r = -r;
- if (y1 < y2)
- {
- for (y=y1+1,x=(x1<<16)+0x8000+r; y<=y2; y++,x+=r)
- psetWithPen((x>>16),y,col,pen,YES);
- }
- else
- {
- for (y=y1-1,x=(x1<<16)+0x8000+r; y>=y2; y--,x+=r)
- psetWithPen((x>>16),y,col,pen,YES);
- }
- }
- }
-
-
- /*--------------------------------------------------------*/
- /* 「にじみペン」手続き */
- /*--------------------------------------------------------*/
-
- #define BLOT_METHOD 1
- // 0=従来どおり(画面上で混色) 1=編集バッファと混色
-
- void blot_plot(int x, int y, int color, int branch, int depth)
- // 3万色編集時専用。
- // branch : 枝分かれする数
- // depth : 何回再帰するか
- {
- if (mode != MODE32K || depth <= 0)
- return;
- int mixr,mixr0;
- mixr0 = getmixrate();
- int max_x, max_y;
- max_x = EIMgetxsize() - 1;
- max_y = EIMgetysize() - 1;
- void blot_plot_sub(int x, int y, int color, int branch, int depth,
- deci grad, deci gradsub)
- {
- if (depth <= 0 || grad <= 0 ||
- x < 0 || y < 0 || max_x < x || max_y < y)
- {
- return;
- }
- if (mixr0 == 256)
- EIMgraypset(x,y,color,DeciToInt(grad));
- else
- {
- char *cp; int conc,t;
- conc = DeciToInt(grad);
- cp = cbuf_adrs(x,y);
- t = cbuf_mix(cbuf2conc(*cp), conc, mixr0);
- *cp = conc2cbuf(t);
- EIMpset(x,y,
- mixcol(EIMpoint_back(x,y),color,t,NO),
- DrawNORMAL);
- }
- int b;
- for (b = 0; b < branch; b++)
- {
- int nx,ny;
- nx = x + rand() % 3 - 1;
- ny = y + rand() % 3 - 1;
- blot_plot_sub(nx,ny,color,branch,depth-1,grad-gradsub,gradsub);
- }
- }
- if (mixr0 == 256)
- blot_plot_sub(x,y,color,branch,depth,IntToDeci(50),IntToDeci(50)/depth);
- else
- {
- mixr = mixr0 / 5;
- blot_plot_sub(x,y,color,branch,depth,IntToDeci(mixr),IntToDeci(mixr)/depth);
- }
- }
-
- /*--------------------------------------------------------*/
- /* にじみペン part 2 */
- /*--------------------------------------------------------*/
-
- void blot2_plot(int x0, int y0, int color, int branch, int depth)
- // 3万色編集時専用。
- // branch : 枝分かれする数
- // depth : 何回再帰するか
- {
- static int dxy[][2] = {
- {0,-1}, {1,-1}, {1,0}, {1,1}, {0,1}, {-1,1}, {-1,0}, {-1,-1}
- };
- if (mode != MODE32K || depth <= 0)
- return;
- int mixr,mixr0;
- mixr0 = getmixrate();
- int max_x, max_y;
- max_x = EIMgetxsize() - 1;
- max_y = EIMgetysize() - 1;
- void blot_plot_sub(int x, int y, int color, int branch, int depth,
- deci grad, deci gradsub, int dir)
- {
- if (depth <= 0 || grad <= 0 ||
- x < 0 || y < 0 || max_x < x || max_y < y)
- {
- return;
- }
- if (mixr0 == 256)
- EIMgraypset(x,y,color,DeciToInt(grad));
- else
- {
- char *cp; int conc,t;
- conc = DeciToInt(grad);
- cp = cbuf_adrs(x,y);
- t = cbuf_mix(cbuf2conc(*cp), conc, mixr0);
- *cp = conc2cbuf(t);
- EIMpset(x,y,
- mixcol(EIMpoint_back(x,y),color,t,NO),
- DrawNORMAL);
- }
- int b;
- for (b = 0; b < branch; b++)
- {
- int d;
- do { d = rand() & 7; } while (d == dir);
- if (dir<0) dir=d;
- blot_plot_sub(x+dxy[d][0],y+dxy[d][1],
- color, branch, depth-1, grad-gradsub, gradsub, dir);
- }
- }
- if (mixr0 == 256)
- blot_plot_sub(x0,y0,color,branch,depth,IntToDeci(50),IntToDeci(50)/depth,-1);
- else
- {
- mixr = mixr0 / 5;
- blot_plot_sub(x0,y0,color,branch,depth,IntToDeci(mixr),IntToDeci(mixr)/depth,-1);
- }
- }
-
- // ●エアブラシ
-
- // static int ab_r,ab_x,ab_y,ab_c;
- static short *airbrush_buf = NULL;
-
- static int airbrush_init(void)
- {
- if (airbrush_buf != NULL)
- free(airbrush_buf);
- airbrush_buf = calloc(2,(spray_r*2+1)*(spray_r*2+1));
- if (airbrush_buf == NULL)
- return -1;
- int x,y;
- int idx=0;
- if (spray_r > 0)
- {
- for (y=-spray_r; y<=spray_r; y++)
- for(x=-spray_r; x<=spray_r; x++,idx++)
- {
- deci r = ID(x*x+y*y) / (spray_r*spray_r);
- if (r<=ID(1))
- {
- airbrush_buf[idx] = 32 - DI(32*r);
- }
- }
- }
- else
- airbrush_buf[0] = 32;
- return 0;
- }
-
- static void airbrush_end(void)
- {
- free(airbrush_buf);
- airbrush_buf = NULL;
- }
-
- void plot_airbrush_start(void)
- {
- }
-
- void plot_airbrush(int x, int y)
- {
- int maxx,maxy;
- maxx = EIMgetxsize()-1;
- maxy = EIMgetysize()-1;
- int x1,y1,x2,y2,xl,x0,y0;
- x1 = _max(0, (x0 = x - spray_r));
- y1 = _max(0, (y0 = y - spray_r));
- x2 = _min(maxx, x + spray_r);
- y2 = _min(maxx, y + spray_r);
- xl = spray_r * 2 + 1;
- int i;
- int idx = xl * (y1-y0) + (x1-x0);
- for (i=y1; i<=y2; i++,idx+=xl)
- {
- EIMgrayhline_map(x1,x2,i,forecol,&airbrush_buf[idx],YES);
- }
- }
-
- /*--------------------------------------------------------*/
- /* 描画アルゴリズム */
- /*--------------------------------------------------------*/
-
- void do_line(int x1,int y1,int x2,int y2,void func(int x,int y)!)
- {
- int xr,yr,r,x,y;
- xr=abs(x2-x1),yr=abs(y2-y1);
- func(x1,y1); // 最初の点
- if (xr==0 && yr==0)
- ;
- else if (xr > yr)
- {
- r=(yr<<16)/xr; if(y1>y2) r=-r;
- if (x1 < x2)
- for (x=x1+1,y=(y1<<16)+0x8000+r; x<=x2; x++,y+=r)
- func(x,(y>>16));
- else
- for (x=x1-1,y=(y1<<16)+0x8000+r; x>=x2; x--,y+=r)
- func(x,(y>>16));
- }
- else
- {
- r=(xr<<16)/yr; if(x1>x2) r=-r;
- if (y1 < y2)
- for (y=y1+1,x=(x1<<16)+0x8000+r; y<=y2; y++,x+=r)
- func((x>>16),y);
- else
- for (y=y1-1,x=(x1<<16)+0x8000+r; y>=y2; y--,x+=r)
- func((x>>16),y);
- }
- }
-
- void do_boxline(int x1,int y1,int x2,int y2,void func(int x,int y)!)
- {
- int i;
- if (x2<x1) swap(x1,x2);
- if (y2<y1) swap(y1,y2);
- for(i=x1;i<=x2;i++) func(i,y1);
- if(y1<y2)
- for(i=x1;i<=x2;i++) func(i,y2);
- for(i=y1+1;i<y2;i++) func(x1,i);
- if(x1<x2)
- for(i=y1+1;i<y2;i++) func(x2,i);
- }
-
- void do_boxfill(int x1,int y1,int x2,int y2,void func(int x1,int x2,int y)!)
- {
- int i;
- if (x2<x1) swap(x1,x2);
- if (y2<y1) swap(y1,y2);
- for(i=y1;i<=y2;i++) func(x1,x2,i);
- }
-
- void do_ellipse(int x,int y,int rx,int ry,void func(int x,int y)!)
- {
- #if 0
- #define ELLIPSE(RX,RY,X0,Y0,X1,Y1) \
- { \
- int x0=RX,s=x0; \
- int y0=0; \
- int px0=-1,py0=-1,px1=-1,py1=-1; \
- while(x0>=y0) \
- { \
- int x1=x0*RY/RX; \
- int y1=y0*RY/RX; \
- if(px0!=X0||py1!=Y1) \
- { \
- func(x+X0,y+Y1);if(X0!=0)func(x-X0,y+Y1); \
- if (Y1!=0) \
- { func(x+X0,y-Y1);if(X0!=0)func(x-X0,y-Y1); } \
- } \
- if (py0!=Y0||px1!=X1) \
- { \
- func(x+Y0,y+X1);if(Y0!=0)func(x-Y0,y+X1); \
- if (X1!=0) \
- { func(x+Y0,y-X1);if(Y0!=0)func(x-Y0,y-X1); } \
- } \
- s-=2*y0+1; if(s<0)s+=2*(x0-1),x0--; \
- y0++; \
- px0=X0,py0=Y0,px1=X1,py1=Y1; \
- } \
- }
- #
- if (rx==0 && ry==0)
- func(x,y);
- else if (rx>ry)
- ELLIPSE(rx,ry,x0,y0,x1,y1)
- else
- ELLIPSE(ry,rx,x1,y1,x0,y0)
- #undef ELLIPSE
- #endif
- if (rx==0 && ry==0)
- { func(x,y); return; }
- int px,py,prey;
- int a2,b2;
- int c1,c2;
- int e;
- a2=rx*rx,b2=ry*ry;
- px=0,py=ry;
- c1=4*b2,c2=8*a2;
- e=a2*(1-4*ry);
- while(b2*px<=a2*py)
- {
- func(x+px,y+py); if(px!=0)func(x-px,y+py);
- func(x+px,y-py); if(px!=0)func(x-px,y-py);
- prey=py;
- e+=c1*(2*px+1),px++; if(e>0) e-=c2*py,py--;
- }
- px=rx,py=0;
- c1=4*a2,c2=8*b2;
- e=b2*(1-4*rx);
- while(a2*py<=b2*px && py<prey)
- {
- func(x+px,y+py); if(px!=0)func(x-px,y+py);
- if(py!=0) { func(x+px,y-py); if(px!=0)func(x-px,y-py); }
- e+=c1*(2*py+1),py++; if(e>0) e-=c2*px,px--;
- }
- }
-
- void do_ellipsefill(int x,int y,int rx,int ry,void func(int x1,int x2,int y)!)
- {
- #if 0
- #define ELLIPSE(RX,RY,X0,Y0,X1,Y1) \
- { \
- int x0=RX,s=x0; \
- int y0=0; \
- int py0,py1; \
- py0=py1=INT_MIN; \
- while(x0>=y0) \
- { \
- int x1=x0*RY/RX; \
- int y1=y0*RY/RX; \
- if (y+Y1 != py0) \
- { \
- py0=y+Y1; \
- func(x-X0,x+X0,py0); \
- func(x-X0,x+X0,y-Y1); \
- } \
- if (y+X1 != py1) \
- { \
- py1=y+X1; \
- func(x-Y0,x+Y0,py1); \
- func(x-Y0,x+Y0,y-X1); \
- } \
- s-=2*y0-1; if(s<0)s+=2*(x0-1),x0--; \
- y0++; \
- } \
- }
- #
- if (rx==0&&ry==0)
- func(x,x,y);
- else if (rx>ry)
- ELLIPSE(rx,ry,x0,y0,x1,y1)
- else
- ELLIPSE(ry,rx,x1,y1,x0,y0)
- #undef ELLIPSE
- #endif
- if (rx==0 && ry==0)
- { func(x,x,y); return; }
- int px,py,prey;
- int a2,b2;
- int c1,c2;
- int e;
- a2=rx*rx,b2=ry*ry;
- px=0,py=ry;
- c1=4*b2,c2=8*a2;
- e=a2*(1-4*ry);
- prey=-1;
- while(b2*px<=a2*py)
- {
- e+=c1*(2*px+1);
- if(e>0)
- {
- func(x-px,x+px,y+py); func(x-px,x+px,y-py);
- prey=py;
- e-=c2*py,py--;
- }
- px++;
- }
- px=rx,py=0;
- c1=4*a2,c2=8*b2;
- e=b2*(1-4*rx);
- while(a2*py<=b2*px && py<prey)
- {
- func(x-px,x+px,y+py);
- if(py!=0) func(x-px,x+px,y-py);
- e+=c1*(2*py+1),py++; if(e>0) e-=c2*px,px--;
- }
- }
-
- /*--------------------------------------------------------*/
- /* 「自由線」コマンド */
- /*--------------------------------------------------------*/
-
-
- extern void put_pencol(), get_pencol();
-
-
- static void commandPFline_sub(int cmd)
- // cmd 0:fline 1:pset
- {
- if (cmd == 8)
- {
- if (airbrush_init() != 0)
- return;
- }
- bool drawing;
- int px,py;
- drawing = NO;
- for (;;)
- {
- DMdispcsr(ms.x,ms.y);
- do
- {
- ms_get(&ms);
- } while (ms.dx==0 && ms.dy==0 && ms.btn1==OFF && ms.btn2==OFF &&
- key_chk() == 0);
- DMerasecsr();
- scrollForCsr(1,1);
- if (ms.btn2==OFFON)
- break;
- else if (ms.btn1==OFFON)
- {
- EIMbackup();
- drawing = YES;
- px = DMimage_getx(ms.x), py = DMimage_gety(ms.y);
- switch (cmd)
- {
- case 0:
- case 1:
- cbuf_clear();
- psetWithPen(px,py,forecol,getcurpen(),YES);
- break;
- case 2:
- cbuf_clear();
- blot_plot(px,py,forecol,1,blot_depth);
- break;
- case 3:
- plot_pen_diffuse(px,py,getcurpen());
- break;
- case 4:
- plot_pen_sand(px,py,getcurpen());
- break;
- case 5:
- get_pencol(px,py,getcurpen());
- break;
- case 6:
- do_paint(px,py);
- break;
- case 7: // freetest
- cbuf_clear();
- blot2_plot(px,py,forecol,1,blot_depth);
- break;
- case 8:
- cbuf_clear();
- plot_airbrush_start();
- plot_airbrush(px,py);
- break;
- }
- }
- else if (ms.btn1==ON)
- {
- if (drawing)
- {
- int nx,ny;
- nx = DMimage_getx(ms.x), ny = DMimage_gety(ms.y);
- switch (cmd)
- {
- case 0:
- if (px!=nx||py!=ny)
- {
- if (ryosuke && pen_isdottype(getcurpen()))
- aaline(px,py,nx,ny,forecol,getcurpen(),256);
- else
- lineWithPen(px,py,nx,ny,forecol,getcurpen(),NO);
- }
- break;
- case 1:
- if (px!=nx||py!=ny)
- psetWithPen(nx,ny,forecol,getcurpen(),YES);
- break;
- case 2: // にじみペン
- blot_plot(nx,ny,forecol,1,blot_depth);
- break;
- case 3: // ぼかしペン
- if (px!=nx||py!=ny)
- plot_pen_diffuse(nx,ny,getcurpen());
- break;
- case 4: // ザラザラペン
- if (px!=nx||py!=ny)
- plot_pen_sand(nx,ny,getcurpen());
- break;
- case 5: // 摩筆
- if (px!=nx||py!=ny)
- put_pencol(nx,ny,getcurpen());
- break;
- case 7: // freetest
- blot2_plot(px,py,forecol,1,blot_depth);
- break;
- case 8:
- plot_airbrush(px,py);
- break;
- }
- px=nx;
- py=ny;
- }
- }
- else
- drawing = NO;
- }
- if (cmd == 8)
- airbrush_end();
- }
-
-
- void commandPFline()
- {
- commandPFline_sub(0);
- }
-
-
- void commandPFPset()
- {
- commandPFline_sub(1);
- }
-
-
- void commandBlot()
- {
- commandPFline_sub(2);
- }
-
-
- void commandDiffuse()
- {
- commandPFline_sub(3);
- }
-
-
- void commandSand()
- {
- commandPFline_sub(4);
- }
-
-
- void commandGoshi()
- {
- commandPFline_sub(5);
- }
-
-
- void commandPaint()
- {
- commandPFline_sub(6);
- }
-
-
- void commandFreeTest()
- {
- // commandPFline_sub(7); // blot2
- commandPFline_sub(8); // air-brush
- }
-
-
- static void commandPolygon_sub(void func()!, bool eachbackup)
- // func : (x1,x2,y) の引数で呼び出される
- {
- bool first = YES;
- for (;;)
- {
- if (area_input(AREA_POLYGON) != 0)
- break;
- if (eachbackup)
- EIMbackup();
- else
- {
- if (first)
- EIMbackup();
- first = NO;
- }
- int ax1,ay1,ax2,ay2;
- area_getboundxy(&ax1,&ay1,&ax2,&ay2);
- int x,y;
- for (y=ay1; y<=ay2; y++)
- {
- x = ax1 + area_chkxylen(ax1,ax2,y,YES);
- while (x<=ax2)
- {
- int l;
- if ((l = area_chkxylen(x,ax2,y,NO)) == 0)
- break;
- func(x,x+l-1,y);
- x += l + area_chkxylen(x+l,ax2,y,YES);
- }
- }
- }
- }
-
-
- void commandDiffuseArea()
- {
- void diffuse_hline(int x1,int x2,int y)
- {
- int i;
- for (i=x1; i<=x2; i++)
- plot_diffuse(i,y);
- }
- commandPolygon_sub(diffuse_hline,YES);
- }
-
-
- void commandSharp()
- {
- void sharp_hline(int x1,int x2,int y)
- {
- int i;
- for (i=x1; i<=x2; i++)
- plot_sharp(i,y);
- }
- commandPolygon_sub(sharp_hline,NO);
- }
-
-
- void commandSandArea()
- {
- void sand_hline(int x1,int x2,int y)
- {
- int i;
- for (i=x1; i<=x2; i++)
- plot_sand(i,y);
- }
- commandPolygon_sub(sand_hline,YES);
- }
-
-
- void cmd_polygon()
- {
- int mix = getmixrate();
- void hline(int x1,int x2,int y)
- {
- EIMgrayhline(x1,x2,y,forecol,mix,NO);
- }
- commandPolygon_sub(hline,YES);
- }
-
-
- /*--------------------------------------------------------*/
- /* 文字表示 */
- /*--------------------------------------------------------*/
-
-
- #if 0
- static void grp_putchar_sub(char *dest, char *src, bool kanji, int col)
- /*
- 1 bit pixel 列を 4 bit pixel 列に変換する
- */
- {
- int i,j;
- uint col_a[8];
- static char bit[] = {128,64,32,16,8,4,2,1};
- col &= 0xf;
- for (i=0; i<8; i++)
- col_a[i] = col << (i*4);
- if (kanji)
- {
- for (i=0; i<16; i++,dest+=8,src+=2)
- {
- *(uint*)dest = *(uint*)(dest+4) = 0;
- for (j=0; j<16; j++)
- if (*(src+j/8) & bit[j%8])
- *(uint*)(dest+(j/8)*4) |= col_a[j%8];
- }
- }
- else
- {
- for (i=0; i<16; i++,dest+=4,src++)
- {
- *(uint*)dest = 0;
- for (j=0; j<8; j++)
- if (*src & bit[j])
- *(uint*)dest |= col_a[j%8];
- }
- }
- }
-
- static void grp_putchar(int x, int y, int c, int col, int style)
- {
- char font[16*16/8];
- para_putBlock par;
- int xlen,ylen,i;
- bool kanji;
- if (c <= 0xff /* 半角文字? */)
- {
- kanji = NO;
- xlen=8, ylen=16;
- FNT_ankRead(xlen,ylen, c, getds(), font);
- if (style & FNT_bold)
- {
- for (i=0; i<16; i++)
- font[i] |= font[i] >> 1;
- }
- }
- else // 全角文字
- {
- kanji = YES;
- xlen=ylen=16;
- FNT_kanjiRead(xlen,ylen, FNT_sjisToJis(c), getds(), font);
- if (style & FNT_bold)
- {
- for (i=0; i<16; i++)
- {
- unsigned int pat;
- pat = (font[i*2] << 8) | font[i*2+1];
- pat |= pat >> 1;
- font[i*2] = pat >> 8, font[i*2+1] = pat & 0xff;
- }
- }
- }
- EGB_writeMode(EGB_work, DrawMATTE);
- EGB_color(EGB_work,3,0);
- #if 0
- par.buf = font;
- par.bufsel = getds();
- par.x1 = x;
- par.y1 = y;
- par.x2 = x + xlen - 1;
- par.y2 = y + ylen - 1;
- if (style & FNT_shadow)
- {
- EGB_color(EGB_work, 0, Black);
- par.x1++, par.y1++, par.x2++, par.y2++;
- EGB_putBlockColor(EGB_work, 0, (char*)&par);
- par.x1--, par.y1--, par.x2--, par.y2--;
- }
- EGB_color(EGB_work, 0, col);
- EGB_putBlockColor(EGB_work, 0, (char*)&par);
- #else
- char grpbuf[16*16/2],grpbuf2[16*16/2];
- grp_putchar_sub(grpbuf,font,kanji,col);
- if (style & FNT_shadow)
- grp_putchar_sub(grpbuf2,font,kanji,Black);
- par.buf = grpbuf;
- par.bufsel = getds();
- par.x1 = x;
- par.y1 = y;
- par.x2 = x + xlen - 1;
- par.y2 = y + ylen - 1;
- if (style & FNT_shadow)
- {
- par.buf = grpbuf2;
- par.x1++, par.y1++, par.x2++, par.y2++;
- EGB_putBlock(EGB_work, 0, (char*)&par);
- par.x1--, par.y1--, par.x2--, par.y2--;
- par.buf = grpbuf;
- }
- EGB_putBlock(EGB_work, 0, (char*)&par);
- #endif
- }
-
- #endif
-
-
- void ART_putstr_style(int x, int y, char *str, int col, int style)
- {
- #if 1
- EGB_fontStyle(EGB_work, style);
- EGB_color(EGB_work, 1, Black);
- grp_putstr(x,y,str,col);
- #else
- int c;
- for (;;)
- {
- if (*str == 0)
- break;
- if (iskanji(*str))
- {
- c = *str * 256 + *(str+1);
- grp_putchar(x,y,c,col,style);
- str++,str++;
- x += 16;
- }
- else
- {
- c = *str;
- grp_putchar(x,y,c,col,style);
- str++;
- x += 8;
- }
- }
- #endif
- }
-
-
- void ART_putstr(int x, int y, char *str, int col)
- {
- ART_putstr_style(x,y,str,col,0);
- }
-
-
- void ARTputstr12(int x,int y, char *str, int forecol, int backcol)
- {
- #define PUTBITBLOCK(x1,y1,x2,y2,dat) { \
- char para[16]; DWORD(para)=(unsigned int)dat; WORD(para+4)=getds(); \
- WORD(para+6)=x1; WORD(para+8)=y1; WORD(para+10)=x2; WORD(para+12)=y2; \
- EGB_putBlockColor(EGB_work, 0, para); }
- int ds = getds();
- char fontbuf[24];
- EGB_color(EGB_work, 0, forecol);
- EGB_writeMode(EGB_work, DrawNORMAL);
- while (*str != 0)
- {
- if (*str == '\a')
- {
- putpict(x,y,Partemis);
- while (*str == '\a') str++;
- x += 52;
- }
- else if (_iskanji(*str))
- {
- int ofs, sjis = (*str)*256 + *(str+1), jis;
- jis = FNT_sjisToJis(sjis);
- if (_iskanji1(sjis))
- {
- ofs = ( ((jis>>8)-0x21)*94 + (jis&0xff) - 0x21)*24 + 0xc00;
- _movedata(font12seg, ofs, ds, (uint)fontbuf, 24);
- }
- else // 第1水準じゃない場合
- {
- char font16buf[32];
- FNT_kanjiRead(16,16,jis,ds,font16buf);
- memset(fontbuf,0,24);
- int di=0;
- for (int i=0; i<16; i++)
- {
- ushort p;
- p = ((ushort)font16buf[i*2]<<8) | font16buf[i*2+1];
- p = (p&0xc000) | ((p&0x3c00)<<1) | ((p&0x3c0)<<2) |
- ((p&0x3c)<<3) | ((p&0x3)<<4);
- fontbuf[di*2] |= (p>>8) & 0xff;
- fontbuf[di*2+1] |= p & 0xff;
- if (i!=1 && i!=4 && i!=7 && i!=10)
- di++;
- }
- }
- PUTBITBLOCK(x,y,x+11,y+11,fontbuf);
- str++,str++;
- x += 12;
- }
- else
- {
- if (*str != ' ')
- {
- int ofs = (int)*str * 12;
- _movedata(font12seg, ofs, ds, (uint)fontbuf, 12);
- PUTBITBLOCK(x,y,x+5,y+11,fontbuf);
- }
- str++;
- x += 6;
- }
- }
- }
-
-
- /* end of subgrp.c */
-